package com.example.demo.controller;

import com.example.demo.dto.ApiResponse;
import com.example.demo.entity.UploadedFile;
import com.example.demo.repository.UploadedFileRepository;
import com.example.demo.security.JwtUtils;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RestController
@RequestMapping("/api/files")
public class FileController {
    private static final String UPLOAD_DIR = "static/upload/";

    @Autowired
    private UploadedFileRepository fileRepository;

    private final UserService userService;

    @Autowired
    private JwtUtils jwtUtils;

    public FileController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/upload")
    public ApiResponse<FileInfoDTO> uploadFile(
            @RequestParam("file") MultipartFile file,
            Authentication authentication) {

        if (file.isEmpty()) {
            return ApiResponse.error(400, "文件不能为空文件");
        }

        try {
            // 1. 准备上传目录
            Path uploadPath = Paths.get(UPLOAD_DIR);
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 2. 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String uniqueFilename = UUID.randomUUID() + fileExtension;
            Path filePath = uploadPath.resolve(uniqueFilename);

            // 3. 保存文件
            Files.copy(file.getInputStream(), filePath);

            // 4. 获取当前用户
            String username = authentication.getName();
            String nickname = userService.getName(username);

            // 5. 保存到数据库
            UploadedFile uploadedFile = new UploadedFile();
            uploadedFile.setOriginalFilename(originalFilename);
            uploadedFile.setStoredFilename(uniqueFilename);
            uploadedFile.setFilePath(filePath.toString());
            uploadedFile.setSize(file.getSize());
            uploadedFile.setContentType(file.getContentType());
            uploadedFile.setUploaderUsername(username);
            uploadedFile.setUser(nickname);

            fileRepository.save(uploadedFile);

            // 6. 返回响应
            return ApiResponse.success("上传成功",new FileInfoDTO(
                    uploadedFile.getId(),
                    originalFilename,
                    "/api/files/download/" + uniqueFilename,
                    username,
                    file.getSize(),
                    uploadedFile.getUploadTime(),
                    file.getContentType(),
                    nickname
            ));

        } catch (IOException e) {
            return ApiResponse.error(500, "文件上传失败");
        }
    }

    @PostMapping("/list")
    public ApiResponse<List<FileInfoDTO>> getFileList() {
        List<UploadedFile> files = fileRepository.findAllByOrderByUploadTimeDesc();

        List<FileInfoDTO> fileInfos = files.stream()
                .map(file -> new FileInfoDTO(
                        file.getId(),
                        file.getOriginalFilename(),
                        "/api/files/download/" + file.getStoredFilename(),
                        file.getUploaderUsername(),
                        file.getSize(),
                        file.getUploadTime(),
                        file.getContentType(),
                        file.getUser()
                ))
                .collect(Collectors.toList());

        return ApiResponse.success(200, "获取成功", fileInfos);
    }

    @PostMapping("/wefiles")
    public ApiResponse<List<FileInfoDTO>> getMyFiles(Authentication authentication) {
        String username = authentication.getName();
        List<UploadedFile> files = fileRepository.findByUploaderUsername(username);

        List<FileInfoDTO> fileInfos = files.stream()
                .map(file -> new FileInfoDTO(
                        file.getId(),
                        file.getOriginalFilename(),
                        "/api/files/download/" + file.getStoredFilename(),
                        username,
                        file.getSize(),
                        file.getUploadTime(),
                        file.getContentType(),
                        file.getUser()
                ))
                .collect(Collectors.toList());

        return ApiResponse.success(200, "获取成功", fileInfos);
    }

    @GetMapping("/download/{filename}")
    public ResponseEntity<Resource> downloadFile(@PathVariable String filename) throws IOException {
        Path filePath = Paths.get(UPLOAD_DIR).resolve(filename);
        Resource resource = new UrlResource(filePath.toUri());

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION,
                        "attachment; filename=\"" + resource.getFilename() + "\"")
                .body(resource);
    }

    @DeleteMapping("/Delete/{id}")
    public ApiResponse<Void> deleteFile(
            @PathVariable Long id,
            Authentication authentication) {

        // 获取当前登录用户
        String username = authentication.getName();

        // 查找文件记录
        UploadedFile file = fileRepository.findById(id).orElse(null);
        if (file == null) {
            return ApiResponse.error(404, "文件不存在");
        }

        // 验证删除权限：仅允许上传者和管理员删除
        if (!file.getUploaderUsername().equals(username) && !userService.authPress(username).equals("e56e1e0d96783898")) {
            return ApiResponse.error(403, "无权删除此文件");
        }

        try {
            // 构造文件存储路径
            Path filePath = Paths.get(UPLOAD_DIR).resolve(file.getStoredFilename());
            // 删除物理文件（如果存在）
            Files.deleteIfExists(filePath);
        } catch (IOException e) {
            return ApiResponse.error(500, "文件删除失败");
        }

        // 删除数据库记录
        fileRepository.delete(file);

        return ApiResponse.success("文件删除成功");
    }

    // 文件信息DTO
    public record FileInfoDTO(
            Long id,
            String originalFilename,
            String downloadUrl,
            String uploaderUsername,
            long size,
            Date uploadTime,
            String contentType,
            String user
    ) {}
}